package com.anji.plus.modules.rules.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.anji.plus.code.ResponseCode;
import com.anji.plus.gaea.curd.mapper.GaeaBaseMapper;
import com.anji.plus.gaea.exception.BusinessExceptionBuilder;
import com.anji.plus.modules.rules.dao.GaeaRulesMapper;
import com.anji.plus.modules.rules.dao.entity.GaeaRules;
import com.anji.plus.modules.rules.service.GaeaRulesService;
import com.anji.plus.util.CustomStringJavaCompiler;
import com.googlecode.aviator.AviatorEvaluator;
import com.googlecode.aviator.Expression;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.Map;
import java.util.regex.Pattern;

/**
 * (GaeaRules)ServiceImpl
 *
 * @author lirui
 * @since 2021-03-12 10:38:19
 */
@Service
public class GaeaRulesServiceImpl implements GaeaRulesService {
    Logger logger = LoggerFactory.getLogger(GaeaRulesServiceImpl.class);

    @Autowired
    private GaeaRulesMapper  gaeaRulesMapper;

    @Override
    public GaeaBaseMapper<GaeaRules> getMapper() {
        return  gaeaRulesMapper;
    }

    @Override
    public String executeRules(String ruleCode, String ruleContent,String rulesDemo) {

        Map<String, Object> ruleDataMap = JSONObject.parseObject(rulesDemo);
        if (StringUtils.isBlank(ruleCode) || StringUtils.isBlank(ruleContent)
            || ruleDataMap == null || ruleDataMap.size() ==0) {
            throw BusinessExceptionBuilder.build(ResponseCode.PARAM_IS_NULL);
        }
        // 是否为类  单一公式
        if (ruleContent.indexOf("class") == -1) {
            // 数据转换
            ruleDataMap.forEach((k, v) -> {
                if (isNumeric(String.valueOf(v))) {
                    ruleDataMap.put(k, new BigDecimal(String.valueOf(v)));
                }
            });
            Expression compileExp;
            try {
                compileExp = AviatorEvaluator.compile(ruleContent);
            } catch (Exception e) {
                logger.info("编译失败: " + e);
                throw BusinessExceptionBuilder.build(ResponseCode.RULE_CONTENT_COMPILE_ERROR);
            }
            String result;
            try {
                result = compileExp.execute(ruleDataMap).toString();
            } catch (Exception e) {
                logger.info("运行异常: " + e);
                throw BusinessExceptionBuilder.build(ResponseCode.RULE_CONTENT_EXECUTE_ERROR);
            }
            return result;
        }
        CustomStringJavaCompiler compiler = new CustomStringJavaCompiler(ruleContent);
        boolean res = compiler.compiler();
        if (res) {
            logger.info("编译成功, compilerTakeTime：" + compiler.getCompilerTakeTime());
            try {
                compiler.runMethod(ruleDataMap);
                logger.info("runTakeTime：" + compiler.getRunTakeTime());
            } catch (Exception e) {
                logger.info("运行异常: " + e);
                throw BusinessExceptionBuilder.build(ResponseCode.RULE_CONTENT_EXECUTE_ERROR);
            }
            logger.info(compiler.getRunResult());
            logger.info("诊断信息：" + compiler.getCompilerMessage());
        } else {
            logger.info("编译失败: " + compiler.getCompilerMessage());
            throw BusinessExceptionBuilder.build(ResponseCode.RULE_CONTENT_EXECUTE_ERROR);
        }
        return compiler.getRunResult();
    }

    // 判断一个字符串是否为数字
    private static boolean isNumeric(String str) {
        Pattern pattern = Pattern.compile("-?[0-9]+.*[0-9]*");
        return pattern.matcher(str).matches();
    }
}
